﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;
using ServerAdder.DAO.TODB;
using ServerAdder.Common;
using System.Threading.Tasks;
using System.Data.EntityClient;
using System.Data.Objects;
using ServerAdder.Core.Model;

namespace ServerAdder
{
    public partial class Form1 : Form
    {
        private DAO.TODB.TODBEntities TODB = new DAO.TODB.TODBEntities();
        private List<Task> taskList = new List<Task>();
        private DAO.TODB.Server server;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void AddingWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //validate input
            if (e.Argument == null) return;
            string server = (string)e.Argument;

            Add(server);

            BeginInvoke((MethodInvoker)delegate
            {
                btnAdd.Enabled = true;
            });
        }
        private void AddingWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage > 0 && e.ProgressPercentage <= 100)               
                progressStatus.Value = e.ProgressPercentage;

        }
        private void Add(string server)
        {
            int i = 0;
            try
            {
                //Add to TODB
                AddingWorker.ReportProgress(0);
                var todbServerEnt = TODB.Servers.Where(s => s.Link == server).FirstOrDefault();
                if (todbServerEnt == null)
                {
                    TODB.Servers.AddObject(new DAO.TODB.Server()
                    {
                        BotVersion = 42,
                        TravianVersion = 42,
                        Comment = string.Empty,
                        Country = server.Split('.').Last(),
                        EndDate = null,
                        IsLock = 0,
                        Link = server,
                        Speed = server.Contains("tx3") ? (short)3 : (short)1,
                        StartDate = DateTime.Now,
                    });
                    TODB.SaveChanges();
                }
                i++;
                AddingWorker.ReportProgress(50);


                //Add to privateServer
                //var privateServerEnt = bulDB.Servers.Where(s => s.Link == server).FirstOrDefault();
                //if (privateServerEnt == null)
                //{
                //    bulDB.Servers.AddObject(new DAO.Bulgari.Server() { Link = server });
                //    bulDB.SaveChanges();
                //}

                //finisehd
                AddingWorker.ReportProgress(100);
            }
            catch (Exception)
            {
                ShowError(i);
            }
        }

        private void DisplayUsers<T>(List<T> users)
        {
            grvUser.DataSource = null;
            grvUser.DataSource = users;
        }
        private void DisplayServers<T>(List<T> servers)
        {
            grvServer.DataSource = null;
            grvServer.DataSource = servers;

            /*
            if (server == null)
                return;

                string serverInfo = string.Empty;
                serverInfo = string.Format(
@"id:{0}\n
link: {1}\n
StartDate: {2}\n
EndDate: {3}\n
Country: {4}\n
IsLock: {5}\n
Speed: {6}\n
BotVer: {7}\n
TravianVer: {8}\n
Comment: {9}\n"
                , server.ServerId, server.Link, server.StartDate, server.EndDate, server.Country, server.IsLock.ToString(), server.Speed, server.BotVersion, server.TravianVersion, server.Comment);

                MessageBox.Show(serverInfo);
             * */
        }
        private string GetValidServerFromGUI()
        {
            string server = txtServer.Text.Trim().Replace(" ", string.Empty);
            if (server[server.Length - 1] == '/')
                server = server.Substring(0, server.Length - 1);
            if (string.IsNullOrWhiteSpace(server)) return string.Empty;

            if (!server.Contains("http://"))
                server = "http://" + server;

            return server;
        }
        private string GetValidUserFromGUI()
        {
            string user = txtUser.Text.Replace(" ",string.Empty);
            if (string.IsNullOrEmpty(user)) return string.Empty;

            return user;
        }
        private void ShowError(int i)
        {
            switch (i)
            {
                case 0: GUIShowError("0 Error"); break;
                case 1: GUIShowError("1: only todb"); break;
                case 2: GUIShowError("2: only bungari"); break;
                case 3: GUIShowError("Finished"); break;
            }
        }
        private void GUIShowError(string msg = null)
        {
            if (msg == null)
                msg = "Error";

            if (this.InvokeRequired)
            {
                this.BeginInvoke(new Action<string>(GUIShowError), msg);
                return;
            }

            //action here 
            MessageBox.Show(msg, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                LocalUser u = Common.Common.Instant.GetUserInformation();
                txtUser.Text = u.Username;
                txtServer.Text = u.Server;

                taskList.Add(new Task(delegate { TODB.Servers.Count(); }));
                taskList[0].Start();

                comboBox1.SelectedIndex = 0;
            }
            catch (Exception)
            {
                GUIShowError();
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                string server = GetValidServerFromGUI();
                if (server == null) return;

                AddingWorker.RunWorkerAsync(server);

                this.btnCheckServer.PerformClick();
            }
            catch (Exception)
            {
                GUIShowError();
            }
        }

        private void btnCheckServer_Click(object sender, EventArgs e)
        {
            try
            {
                string inputServer = GetValidServerFromGUI();
                string inputUsername = GetValidUserFromGUI();

                if (string.IsNullOrEmpty(inputServer)) return;

                var servers = TODB.Servers.Where(item => item.Link == inputServer).ToList();
                DisplayServers(servers);

                server = servers.FirstOrDefault();
                if (server == null || string.IsNullOrEmpty(inputUsername))
                    return;

                var users = TODB.Users.Where(item => item.Username == inputUsername && item.ServerId == server.ServerId).ToList();
                DisplayUsers(users);

                Common.Common.Instant.WriteSetting(inputServer, inputUsername);
            }
            catch (Exception)
            {
                GUIShowError();
            }
        }

        private void btnGetServerList_Click(object sender, EventArgs e)
        {
            try
            {
                Task.WaitAll(taskList.ToArray());
                var servers = TODB.Servers.Select(item => new { Link = item.Link }).Distinct().ToList();
                DisplayServers(servers);
            }
            catch (Exception)
            {
                GUIShowError();
            }

        }

        private void btnRunSQL_Click(object sender, EventArgs e)
        {
            try
            {
                ObjectContext objContext;
                //if (comboBox1.SelectedIndex == 0)
                //{
                objContext = TODB;
                //}
                //else
                //{
                    //objContext = bookex; //this is my private server for another project
                //}

                var cnnString = ((EntityConnection)objContext.Connection).StoreConnection.ConnectionString;
                //validate input
                string query = rtfQuery.SelectedText;
                if(string.IsNullOrEmpty(query)) query = rtfQuery.Text;
                if (string.IsNullOrWhiteSpace(query)) return;

                //Execute query
                DataTable dt = new DataTable();
                dt = ExecuteDataTable(cnnString, query);

                //Update data
                grvServer.DataSource = null;
                grvServer.DataSource = dt;
            }
            catch (Exception)
            {
                GUIShowError();
            }
        }

        public DataTable ExecuteDataTable(string connectionString, string sqlString)
        {
            DataTable dt = new DataTable("Table1"); //The Table name MUST be set in order to pass this over WCF

            using (IDbConnection con = new SqlConnection(connectionString))
            {
                using (IDbCommand cmd = new SqlCommand(sqlString, (SqlConnection)con))
                {
                    cmd.CommandTimeout = 0;

                    using (SqlDataAdapter adapter = new SqlDataAdapter())
                    {
                        adapter.SelectCommand = (SqlCommand)cmd;
                        adapter.Fill(dt);
                    }
                }
            }

            return dt;
        }

        private void btnUpdateServerTo42_Click(object sender, EventArgs e)
        {
            if (server == null)
                return;

            server.TravianVersion = 42;
            TODB.SaveChanges();

            this.btnCheckServer.PerformClick();
        }

        //Process Hot Key : F5
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.F5))
            {
                btnRunSQL.PerformClick();
                return true;
            }


            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void comboBox1_MouseHover(object sender, EventArgs e)
        {
            if (comboBox1.DroppedDown) return;

            comboBox1.DroppedDown = true;
        }
    }
}
